package com.redoor.app.stake.basicdata.aop;

import com.alibaba.druid.support.json.JSONUtils;
import com.aliyun.openservices.shade.com.alibaba.fastjson.parser.ParserConfig;
import com.redoor.app.stake.basicdata.model.BaseHsfOperationLog;
import com.redoor.app.stake.basicdata.model.LogEnum;
import com.redoor.app.stake.basicdata.service.LogService;
import com.redoor.app.stake.common.utils.JsonUtils;
import com.redoor.app.stake.common.utils.UUIDTool;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * HSF接口调用日志记录
 * Created by wangjunlei on 2018/2/24.
 */
@Aspect
@Component
public class HSFServiceLogAspect {
    protected static org.slf4j.Logger logger = LoggerFactory.getLogger(HSFServiceLogAspect.class);

    private Map logMap;
    private BaseHsfOperationLog baseHsfOperationLog;
    @Autowired
    private LogService hsfLogService;
    @Pointcut("execution(!@com.redoor.app.stake.basicdata.aop.IgnoreAopLog * com.redoor.app.stake.basicdata.hsf.service.impl.*.*(..))")
    public void HSFServiceLog() {

    }

    @Before("HSFServiceLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        logMap = new HashMap();
        baseHsfOperationLog = new BaseHsfOperationLog();
        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        baseHsfOperationLog.setUuid(UUIDTool.getUUID());
        baseHsfOperationLog.setClientip(request.getRemoteAddr());
        baseHsfOperationLog.setMethodname(joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        baseHsfOperationLog.setStartat(String.valueOf(System.currentTimeMillis()));
        baseHsfOperationLog.setRequestbody(Arrays.toString(joinPoint.getArgs()));

        logMap.put("URL",request.getRequestURL().toString());
        logMap.put("HTTP_METHOD",request.getMethod());
        logMap.put("IP",request.getRemoteAddr());
        logMap.put("CLASS_METHOD",joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        logMap.put("ARGS",Arrays.toString(joinPoint.getArgs()));
        logMap.put("START_TIME",System.currentTimeMillis());
        // 记录下请求内容
        logger.info("hsf services info : " + JSONUtils.toJSONString(logMap));
    }

    @AfterReturning(returning = "ret", pointcut = "HSFServiceLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求，返回内容
        if(ret instanceof Collection){
            logger.info("RESPONSE LIST SIZE: " + ((Collection) ret).size());
        } else if(ret instanceof Map){
            logger.info("RESPONSE MAP SIZE: " + ((Map) ret).size());
        } else {
            logger.info("RESPONSE : " + ret);
        }
        logMap.put("END_TIME",System.currentTimeMillis());
        logMap.put("RESPONSE",ret);

        baseHsfOperationLog.setEndat(String.valueOf(System.currentTimeMillis()));
        baseHsfOperationLog.setResponsebody(JsonUtils.toJson(ret));
        baseHsfOperationLog.setStatus(1);
        hsfLogService.addLogToRedis(baseHsfOperationLog,LogEnum.HSF_LOG);
    }

    @AfterThrowing(throwing="ex", pointcut = "HSFServiceLog()")
    public void doAferThrowing(Throwable ex){
        logger.info("ERROR_RESPONSE : " + ex.getLocalizedMessage());
        logMap.put("END_TIME",System.currentTimeMillis());
        logMap.put("RESPONSE",ex.getLocalizedMessage());

        baseHsfOperationLog.setEndat(String.valueOf(System.currentTimeMillis()));
        baseHsfOperationLog.setResponsebody(ex.getLocalizedMessage());
        baseHsfOperationLog.setStatus(2);

        hsfLogService.addLogToRedis(logMap,LogEnum.HSF_LOG);
    }
}
